ATARI FLASHBACK BASIC MANUAL
----------------------------

Atari Flashback BASIC is so close to Virtual World BASIC the same manual can be used and most programs can be cross compiled with few changes.

Important differences are:

1. Additional variable arrays cannot be declared, only constant arrays.  
2. The variable arrays for the virtual world and sprite objects remain, however the variable arrays for the player and sprite colors now occupy the first 1.5 rows of the virtual world so if you scroll over that area you will see the color data. 
3. Multiple Virtual Worlds may be defined (see the new keyword loadvirtualworld in chapter 16).

CONTENTS:
---------------------------------------------------------------
0.  Introduction to Virtual World BASIC 
1.  Virtual World BASIC Syntax
2.  Virtual World BASIC Commands
3.  Fun with variable arrays and strings!
4.  Redefining part of a sprite
5.  Printing strings with the print command
6.  Storing ASCII Text in data statements
7.  Scrolling text through sprites or the screen
6.  Array transformations
7.  Raising an event and Chiptunes (also events)
8.  Compiling your program manually 
9.  Using the Visual IDE
10. Debugging your programs 
11. Load Balancing
12. Resources, Examples and Tutorials
13. Old-School BASIC mode
14. Display List Interrupts 
15. Multicolor playfields, sprites, DLI zones
16. Multiple virtual worlds (Flashback BASIC only)
17. Padding small programs (Flashback BASIC only)

Introducing Virtual World BASIC
-------------------------------
Virtual World BASIC allows you to create games in BASIC for the Atari 2600 that take place in a virtual world much larger than the Television screen.
 
You have a playfield camera to pan about the virtual world, and sprites which you can bind to virtual world pixels (tile mapping). And, off-screen virtual collision detection.

You design the large virtual world by "drawing it" with ASCII art in your BASIC program. You draw the sprite graphics that way too. 

The BASIC also has a chiptune engine - You define chip tunes that repeat in the background and for specific game events in a table just below your ASCII art.

Virtual World BASIC is designed for programmatically and visually manipulating arrays, graphics and binary strings.

The virtual world contains thousands of pixels that you control programmatically with the vwpixel command. The playfield camera view links relationally to the virtual world and shows a 200 tile pixel view (20x10) on the Television screen whenever you change the cam coordinates. 

vwBASIC's objects can all be addressed as arrays in BASIC, and you can define hundreds of additional variables as named arrays.


Setting up
----------
Extract the files to c:\vwBASIC
(You can create a different folder but you will have to edit the paths in the compiler script).
Now just edit the program.txt file, it's loaded with a sample program you can modify or use as a guide to write new programs. 

Note: for Atari Flashback BASIC, you still want to use the vwBASIC directory; if you have vwBASIC already installed just put the Atari Flashback BASIC files in the same directory - they do not conflict with one another and can cross-compile the same BASIC programs with very vew changes.

Create the subdirectory "c:\vwBASIC\Stella and place a copy of Stella.exe and it's DLL's there. If you do not already have the Stella emulator you can download it from http://stella.sourceforge.net/ 


vwBASIC language syntax
-----------------------
Almost pure TinyBASIC
simple expressions with no parenthesis.
100 e=5*n
is ok, but "e=5*n-3" must be written as two statements:
100 e=5*n:e=e-3

bitwise operators: ^ xor, & and, | or.
number prefixes: none - decimal(255), % binary (%11111111), $ hex ($ff)

if then else
------------
if then else is supported in BASIC horizontal format:
10 if e>=5*n or g*2=r-3 then e=10:i=17 else i=33:e=e+2

Note: You cannot mix and and or in the same if statement (use another if). 
If must always be the first statement in a line.

Language commands:
------------------
vwpixel - sets, flips, polls virtual world pixels and binds sprites to the virtual world. 

Examples:
10 vwpixel(0,0,on):rem turn on upper left pixel in the virtual world.
20 vwpixel(x,y,flip):rem flip the virtual world pixel at x,y.
30 if vwipxel(5,5,poll)>0 then COLUBK=255:rem change background color if virtual world pixel 5,5 is on. 

40 vwpixel(5,5,bindplayer0):rem bind sprite to virtual world pixel 5,5.
45 player0x=player0x+3:player0y=player0y+2: fine grain control
Line 45 shows the fine grain coordinate system variables for the sprite which get set by vwpixel; you can adjust them for fine grain movement between tiles.

10 Loadplayer0(8): rem load second sprite definition from library
---------------------------------
Loads the player 1 sprite with a definition (8 rows of 8 pixels) from the sprite library, starting at the specified index of 8. 

20 loadplayer1upsidedown(0): rem load first sprite def from library
--------------------------------
Loads the player 2 sprite from the sprite library, flipped upside down. You have control over horizontal flip via TIA system var REFP0:
10 REFP1=255:rem flip player 2 horizontally

reading the joysticks
---------------------
Joysticks are read using friendly named variables that return 1 or 0:
10 if joy0left=1 then f=3: rem joystick 0 pushed left
20 if joy1fire=1 then f=4: rem joystick 1 botton pressed

data statements
---------------------
Named variable arrays are declared and initialized in data statements:
90 rem create boats data array, dimension and initialize 
100 data boats 1,3,2,3,2,4,7

read 
---------------------
110 read i(boats,j):rem read element j from boats array into i.
120 i=boats(j):rem read element j from boats array into i.
130 boats(i)=boats(j): rem assign one array element variable to another. 

write [alias: print]
------------------------
120 print %11111111(player0,0):rem print to top row of player 1 sprite.
130 write i(boats,j):rem write value i into boats array at element j.
140 boats(j)=5:rem standard BASIC array syntax is also supported
150 boats(j)=boats(x)*5:rem BASIC array manipulation

For Next loops
---------------------
10 rem nested looping, inner/outer example:
20 for x= 3 to 5: for y = 12 to 2 step -2: vwpixel(x,y,on): next y,x

goto gosub return
---------------------
10 if e=33 then gosub 100 else gosub 200
20 goto 300
200 e=33:return
300 rem

fun with vwBASIC variable arrays and strings!
----------------------------------------------
vwBASIC has a small number of predefined variables in low RAM (e-z,var1,var2,px,py,bx,by and score) and virtually unlimited named variable arrays.

vwBASIC lets you declare and initialize named variable arrays in data statements:

100 data boats 1,3,2,3,2,4,7


Manipulating array variables:
------------------------------------
110 i=boats(0): rem store the first element of boats in i.
120 boats(0)=i+1: rem store i+1 in the first element in boats.
130 boats(0)=boats(3)*2: rem assign one element to a multiple of another 

An alternate array syntax is also supported:

110 read i(boat,0):rem read 1st element of boats into i
120 write i(boats,1):rem write i into 2nd element of boats array.

You can add as many named arrays as you wish. If you reach a total of 255 total element variables for all of your arrays combined, you must start a new array. You can then continue building arrays until 256 additional element variables are reached (255+256 total) and then must start a new array again. It is possible to have over 1,000 bytes of array variables in this manner if you desire it. This is unlikely, but when you're used to working with 26 variables just declaring an extra 50 gives you much more flexibility to code.

Nearly all of the abstract objects in vwBASIC are arrays or multidimensional arrays. If you look at the ASCII art definition for the virtual world and the sprite library, they are binary tabular arrays you can work with visually or programmatically - the virtual world contains 2,000 binary variables and each sprite definition contains 64. 
 
vwBASIC has special commands like vwpixel to address the individual bits in the virtual world, and a load sprite function that reads 8 binary strings out of the sprite library (comprising an 8x8 sprite image) to load one of the system sprite tables, player0 and player1.

Visually redefining part of a sprite:
-------------------------------------
10 print %11111111(player0,0)
20 print %11000011(player0,1)
30 print %11111111(player0,2) 

We just printed three rows of pixels on the player1 sprite, which has 8 rows. Built in functions loadplayer0(n) and loadplayer0upsidedown(n) contain loops that read 8 rows of the sprite library starting at index n and load the player sprites much like this - you can write similar functions in vwBASIC.

Printing strings on the world with the PRINT@ command:
-------------------------------------------------------
You can poll,flip or set the individual pixels or bind the sprites to them with vwpixel but you can also print a binary string to the virtual world, 8 bits at a time much like the BASIC PRINT@ command.

print %10101010(virtualworld,3)
---------------------------------------
Prints the binary pattern block at the position of the 3rd byte - the table is 12 bytes accross to hold the 92 pixel wide virtual world, and 20 bytes deep, as per it's ASCII art definition. You can calculate the @ index by multiplying rows x 12 (row length) and adding to find the target byte column. Note: the first byte in each row is partially obscured. 

storing ASCII text in data statements
-------------------------------------
ASCII text can be easily stored in Data statements with BASIC:
10 data mydata "this is ASCII text"

Scrolling ASCII text through the sprites or the screen (or DLI zones)
---------------------------------------------------------------------
The WARPDRIVE game includes a lot of text in data statements and shows how BASIC can be used to read the ASCII text and scroll it full size through the screen - as a fun BASIC exercise, try modifying the different messages in the game!  


Array transformations
---------------------
The above works because all arrays, regardless of the number of dimensions or type, may also be accessed as a single dimensional byte array. 

You can also read past the end of one array into the next array:

100 i=array1(7):rem can read past boundary into the next array
105 data array1 5,6,7,8
110 data array2 1,2,3,4

The utility in the example above is that you can use the two 4 element arrays individually and combine them as one 8 element array when needed. 

*You can assign one arrays elements to another and reference transformations in expressions just like with scalar variables:

10 array1(n)=array2(3)*7
30 rem BASIC array manipulation syntax

*Note: With ATARI FLASHBACK BASIC you can only assign to the built in RAM variable arrays virtualworld, player0, player1, rowcolors and player0colors (the last two overlap the virtualworld, occupying the first 1.5 rows); Every named array you declare is a a constant array (read only).

Double Buffering in RAM
-----------------------
While virtualworld is the system table array for the virtual world, there is another system table array for the playfield camera, RAMplayfield. This is another buffer that can be modified independently of the virtual world for special effects and a higher resolution playfield. There is no physical object to draw with ASCII art for this table as there is for the virtualworld, because the table is linked relationally and populated from a coordinate view section of the virtual world whenever you raise an event or a DLI.

Relational Database core
------------------------
Commands like vwpixel modify both 2D binary system tables when their coordinates overlap using relational calculus behind the scenes as does raising an event, which creates a playfield camera view table from anywhere within the virtual world table as described below - the playfield CAM is like a sheet of glass that you can annotate and then just wipe off by raising an event or a DLI without moving the camera. 

Raising an event
----------------
Raising an event causes the camera view to refresh at the virtual world  coordinates specified by XIndex and BYTErowoffset (system variables for the playfield CAM). XIndex is the CAM's x coordinate, and BYTErowoffset is the CAM's y*12 coordinate. 

You can raise an event anytime you want by flipping on the system variable to scroll the virtual world:
10 scrollvirtualworldtoggle=1

Raising an event also runs whatever code you've got in the Kitchen sink section using a larger time window to run code - more time than there is in either of the gameloop sections so it's a good place for a long running routine. The event variable is automatically toggled back off (set to 0) until you set it again to raise another event.

Note that events should only be raised conditionally; there is usually no need to raise an event to refresh the playfield camera view unless it's virtual world coordinates have changed, doing so constantly will result in flicker. 

chiptunes
---------
below the ASCII art, there is a table for chiptunes:
chiptunes
7,30,0,0,8
7,24,0,0,8
7,20,0,0,8
7,24,0,0,7
30,0,0,30,0
10,20,5,11,25
7,7,6,5,20
6,4,4,6,10
0,0,0,0,0

The chiptunes table works like this; each line contains data for both voices of the Atari sound chip and a common duration:
frequency, channel, frequency, channel, duration

Music is processed through an fx engine that changes the sound envelope.

The chiptunes table is designed to hold multiple chiptunes; a repeating main theme and multiple sub themes which return control to the main theme.

In this example the first song loops after it reaches a duration of 0 (line 5). 

Playing the next tune
---------------------
Setting the music index (system var MUSICINDEX) to 5 will start the player at the following line (line 6), the second theme in this case. The second theme only plays once - when it reaches a duration of 0 (line 9) it goes back to playing the main theme. 
There is another system variable SUSTAINFORFRAMES that holds the duration value and can be overridden for sound effects along with the channel and frequency variables AUDC0/AUDC1 and AUDF0/AUDF1. 

Compiling your program manually
-------------------------------
First make sure your program is saved as c:\vwBASIC\Program.txt

Next compile your program with the vwBASIC compiler:

Run the vwBASIC_compiler.ps1 script from the shell or command line; it will take the basic program in c:\vwBASIC\Program.txt and compile it into c:\vwBASIC\Program.asm.  
Note: If you are using Atari Flashback BASIC, run the ATARI_FLASHBACK_BASIC_compiler.ps1. 

Note: If you get a message you cannot run the compiler powershell script, you need to enable scripting:
set-executionpolicy -scope CurrentUser -ExecutionPolicy RemoteSigned

Next, assemble your Assembly output file into a ROM binary with dasm*.
from the command line:
dasm c:\vwBASIC\program.asm -oc:\vwBASIC\Program.bin -f3
If there are no BASIC errors (unhandled lines are OK), the compiler will automatically complete this step for you.
If you wish to manually override, you can still compile a program with BASIC errors.

*dasm is included, if your system requires a different version get it here:
http://dasm-dillon.sourceforge.net/

The compiler is configured to launch the ROM in the Atari Emulator (Stella) upon successful compile.

You can also play the ROM binary on real Atari hardware with a ROM flashcart or a custom built cartridge, or SD cart for the Atari Flashback Portable.

Putting games on Tape and CD - Virtual World BASIC only:
The makewav.exe utility for creating WAV files for Tape, compact disc or iPod for the SuperCharger or Cuttle Cart is included. The syntax is:

makewav -ts Program.bin


Using the Visual IDE (NEW! Now integrated)
--------------------------------------------
The Windows Powershell ISE is an excellent visual IDE for vwBASIC:

It's included or free with your Windows OS and Linux. On Windows you can launch it directly from Administrative tools or by running powershell_ise.exe.

1. Go to Start Menu and search for "Windows PowerShell ISE".
Right click and choose "Run as administrator".

2. In the top part, paste "Set-ExecutionPolicy RemoteSigned"
run the script. Choose "Yes".

Note: This is completely safe and will not open your system up to malicious script execution because the default scope is local-machine and your user account that you browse the web with cannot run powershell scripts unless an alternate method is used - and then it must ask your permission first.

1. Load the PowerShell ISE and select the "show script pane right" icon to configure your environment.
2. Load the c:\vwBASIC\vwBASIC_Compiler.ps1 compiler script (or ATARI_FLASHBACK_BASIC_Compiler.ps1 of you are using Atari Flashback BASIC).
3. Load any BASIC program (.bas or .txt file, the IDE always selects the left most one to compile)
4. Edit the program and save your changes.
5. Select the vwBASIC_Compiler.ps1 tab and press Play to compile and launch in Stella:

You'll see the Assembly output flowing through the left pane as the compiler is working.
Click the Program.txt tab to review your code alongside it's Assembly output; the scrollbars let you match up the code.

When the compiler finishes, it either presents an error report showing what program lines need to be fixed, or launches your ROM binary in the Stella emulator (For more information about Stella, visit http://stella.sourceforge.net/). 

Debugging:
----------
Finding syntax errors in your code - these are the most common and frequent BASIC coding errors and easy to find! 

The compiler reports each Syntax Error it finds as well as unhandled lines (What?) of BASIC code it could not understand as illustrated in these examples:

;----UNHANDLED LINES FOUND:
;---------------------------------
;--xxx-unhandled line 79: _68 COLUP0 $84
;--xxx-unhandled line 91: _77 glob blop what
;--xxx-unhandled line 243: _189 rem----------------------subroutines:
;--xxx-unhandled line 244: _190 rem----------------------------------

;----BASIC ERRORS FOUND, REPORT:
;---------------------------------
;check line 90: _76 if z=2 and y<19 y=y+1
;check line 95: _81 if z=2 and y=19 z=1

Note: Unhandled lines (What?) can often be ignored but all Errors must be fixed before your code will compile.

If the compiler fails to find the error for you, DASM may locate it or it may be a complex error that is syntactically correct and requires you trace for it.

Out of Memory error:

Dasm provides this third type of Tiny BASIC error meaning that you are out of memory.
Dasm will complain of a "reverse index" if an out of memory error occurs. You can reduce your code size or transfer some of it to the other gameloop; both gameloops can hold about 6K of BASIC code. Note that gameloop2 shares space for graphics and sound while gameloop1 shares space with named array variables.


Load balancing:
---------------
If the screen rolls (scanline count>262) you are doing too much in a single frame and need to load balance by either moving some of the code to gameloop2 (the other vertical blank), or running it in a different frame; a simple framecounter variable can allow you to split your code up on different branches for different frames to balance it. Remember when you are designing programs that both gameloops run every single frame or many times per second. 
 
Some system variables are write only
------------------------------------
COLUPF, COLUP0, COLUP1 and COLUBK:
These are the system vars that hold the virtualworld color, the player colors and the background colors. 
10 COLUP0=255:COLUP1=$FF:rem set the player colors 
Works, but you cannot read back from these variables.
Some system arrays are read only:

*Do not write to the sprite library table
-----------------------------------------
It is not page aligned so doing this might break the code, the two system sprite tables player0 and player1 are the tables to write to, to update the sprites directly (and they are page aligned). If you want the sprite library to be malleable, you could define your own sprite library in binary table array variables. Ditto for not writing to the music table - it's not page aligned either.

vwBASIC resources:
------------------
Random Terrain's batari BASIC pages are an excellent resource as most of the Atari write-only system variables like COLUPF,COLUP1,COLUP0 and COLUBK (pixel color, player colors, background color) are in common. And there are great tools like color lookup tables and a sound development kit where you can hear the fx you create:

http://www.randomterrain.com/atari-2600-memories-tia-color-charts.htmlhttp://www.randomterrain.com/atari-2600-memories-batari-basic-music-toy.html

Sample program (Tron LightCycles)
----------------------------------
The sample program provides examples of working with vwBASIC functions and language intrinsics and it's unique abilities manipulating arrays:

The camera follows Player 1 about the virtual world, if the button is pressed Player 1 leaves a trail like in Tron/surround. The screen flashes whenever Player 1 drives over an existing virtual world pixel, and the pixel is erased. 

Player 2 can do the same things but the camera doesn't follow them - player 2 can drive off screen. Player 2's virtual world offscreen collisions can be verified by Player 1 following them with the camera.

When Player 2 is leaving a trail, Player 1 becomes animated - three rows of the Player 1 sprite are mapped to the Player 2 sprite. 

Game and Demo Tutorials and examples
------------------------------------
Simple Single Statement Program - BASIC Programming is so easy you can start with a single statement!

StarBlitz - a smooth scroller Defenderesque game where you defend the colorful Cities of Mars from Meteors, Missiles and Space Ships!

KC Munchkin Monster Maze is a limited edition homebrew release that illustrates the effects you can achieve with vwBASIC and a tube Television: 
https://www.youtube.com/watch?v=aghqgf6qqRw
This complex game example uses 50 variables - the 28 scalar variables were not enough, so another 20 array variables were utilized. It also takes advantage of preinitialization to save code space.

The Breakout Adventure Tutorial illustrates the use of variable array manipulations to render scrolling objects over and within a scrolling playfield:
http://atariage.com/forums/topic/240433-demo-scroller-tutorial/

Sample Program Defender III (Atari Flashback BASIC)
----------------------------------------------------
This sample program is for the Atari Flashback, though it could be compiled with the Virtual World BASIC compiler to run on the SuperCharger
with a few changes.

Display List Demo 5 
-------------------
Shows how to set and call DLI's with very simple BASIC commands. The two gameloops where BASIC runs control the top and bottom vertical blanks respectively, allowing for 
alot of processing power and interesting effects with DLI's - this demo creates three seperate screen cams and scrolls the virtual world through them in different
directions and illustrates binding sprites and floating them over the scrolling backgrounds.
 
About the extra colors in the games:
------------------------------------
The Atari can exploit ideosyncracies in the NTSC signal and RF carrier to display artifact colors (multiplying the depth of the bitmap for free to get additional colors). On an antique tube Television this is a very pleasant effect. The Vader and 6-switch models of the Atari produce the strongest artifact colors and moire effects through their RF connection (they leak chroma).

Virtual World BASIC lets you produce artifact colors on virtual world tile pixels and nearby sprites by choosing high luminosity colors for the tile pixels - both of the games above use an array of preselected artifact colors to produce their effects.


Old-School BASIC mode:
----------------------
vwBASIC supports Old-School BASIC programming just like we did it back in the early days of home computing!
No template directives are necessary, though you can add them, same for the ASCII art. It's just Old-School BASIC. All of the system resources are still there and programatically accessible just like bitd.

Remember those fun BASIC type-in's in old-school programming Magazines?

9LineBlitz is a sample Old-School BASIC program you can type-in and run:
---------------------------------------------------------------------------------
0 data city 1,4,2,5,3,2,3,1,4,1,1,1,5,2,2,3,1,4,1,4,3,1,4,4,1,1,2,2,3,1,3,4,5,4,4,3,4,5,1,2,4,1,5,2,2,3,1,3,1,1,4,1
1 if g=0 then for j=0 to 7:player1(j)=189:player0(j)=pl(j):next j:BYTErowoffset=120:COLUPF=$84:COLUP0=$b4 else goto 3 
2 for j=20 to 71:k=j-20:k=city(k)+14:for i=k to 19:vwpixel(j,i,on):next i,j:player0y=88:player0x=94:COLUP1=$74:y=20
9 if i<17 then i=i+1:virtualworld(i)=i*9:goto 9 else for i=19 to 239:virtualworld(i)=0:next i:rem Emulator patch
3 COLUBK=0:AUDV0=0:g=1:scrollvirtualworldtoggle=1:BITIndex=BITIndex+1:data pl 0,224,127,231,252,192,128,0:rem bitmap
4 if joy0fire=1 and y>=20 then AUDF0=6:AUDC0=8:AUDV0=15:x=BITIndex+11:y=11:i=88-player0y:i=i/10:y=y+i
5 if y<21 then vwpixel(x,y,bindplayer1):j=y-10:y=y+1:COLUP1=M(j):data M $64,$54,$b4,$a4,$32,$44,$24,$c4,$94,$f4,$54
6 if y<=19 and vwpixel(x,y,poll)>0 then vwpixel(x,y,flip):player1x=0:player1y=0:AUDC0=y:y=20:AUDF0=4:AUDV0=15  
7 if BITIndex>71 then BITIndex=0:player0y=player0y-2:rem player flies lower each pass over the smoothly scrolling city
8 if CXP0FB>126 then CXCLR=0:g=0:for i=0 to 255:AUDF0=i:AUDV0=i:COLUBK=$34:next i:rem check collision, restart game

There is an annual Old-School BASIC 10 Liner contest (80,120 and 256 character variety) conducted internationally here:
http://gkanold.wix.com/homeputerium#!basic-tenliners-2016/c450

Notice how line 9 is out of sequence? It was added to create compatiblity with emulators, the Atari Flashback Console will require padding (see chapter 17) for small Game programs like this one.

Update: The VCS placed very well in the 2016 contest, beating the C64, Speccy, ZX-81 and MSX machines!


Display List Interrupts (NEW!)
-------------------------------
 Display list interrupts run during the vertical blank and provide the ability to split the screen up into multiple horizontal sections, each of which can contain a vertically, horizontally or diagonally scrolling playfield with free floating or tile-mapped sprites.

The DLI demo programs (DLI_Demo.txt) demonstrates setting up display lists to scroll the top half of the screen vertically while scrolling the bottom half of the screen horizontally at different speeds.

The demo actually uses 4 DLI calls to do this but arranges them to create two contiguous scroll zones.
  
Syntax for calling the DLI is simple: "gosub DLI"
two rows (1/5) of the screen will be updated based on the value you store in scrollvirtualworldtoggle (it's reused for DLI's; just don't use zero).

Put in an 8, and the bottom two rows of the screen will be updated:
100 scrollvirtualworldtoggle=8:gosub DLI:scrollvirtualworldtoggle=0: rem call DLI, update tile rows 9 and 10.

Put in a 1 and rows 2 and 3 will be updated near the top of the screen:
100 scrollvirtualworldtoggle=1:gosub DLI:scrollvirtualworldtoggle=0: rem call DLI, update tile rows 2 and 3.

Trick to span three rows (about 1/3 of the screen) - use "3" as a prefix before the start row.

Put in a 37 and the bottom three rows of the screen will be updated:

100 scrollvirtualworldtoggle=37:gosub DLI:scrollvirtualworldtoggle=0: rem call DLI, update tile rows 8,9 and 10.

Put in a 30 and the top 3 rows will be updated.
100 scrollvirtualworldtoggle=30:gosub DLI:scrollvirtualworldtoggle=0: rem call DLI, update tile rows 1,2 and 3.
  
It's no more complex than setting the x,y coordinates for the playfield camera to pan the view about the virtual world, you're just able to do that independantly for each section of the screen you define with a DLI!

You can call a DLI from each gameloop with different camera settings; each game loop runs on one of the vertical blanks so one of your DLI calls will happen "before" (called from the top blank) the display is drawn and one will happen after the display is drawn, the one called from the bottom blank (gameloop2). 

DLI Overhead:

3 row DLI's will occuply most of the top vertical blank, and will barely fit in the bottom blank while 2 row DLI's leave plenty of space for your own program code in either vertical blank.

Just like raising an event to scroll the entire screen, A DLI need be called only as frequently as you need to update it's target section of the screen (pan the camera for that area only).

Exercises for setting up multiple DLI's and setting their animation rates:

1. Increase the scrolling speed of the top half of the screen to match the bottom, so they are both animated at 30 FPS (every other frame).
   
 2. Change the demo to show three visible scroll zones; try to set up two zones scrolling horizontally in opposite directions or at different speeds, while the third "larger" zone (comprised of two zones) scrolls vertically or diagonally.


Multicolor playfields and DLI zones: (NEW!)
--------------------------------------------
The color of the rows in each DLI zones can be independenlty colored via the rowcolors shadow register array:
*rowcolors 100,110,120,130,140,150,160,170,180,90

If rowcolors is not specified in your program a default fade array is used that can be programatically accessed.

To change the rowcolors shadow register array programatically, simply update it like any array variable.

10 rowcolors(3)=100:rem change the color of the third row of tiles visible.

Multicolor Note: COLUPF is no longer effective; you can only change the playfield color via the shadow register array.


Multicolor sprites: (NEW!)
--------------------------
You can control the color of each row of the first sprite via it's shadow register array:
*player0colors 100,255,100,100,200,200,200,200

If player0colors is not specified in your program a default fade array is used that can be programatically accessed.

10 player0colors(4)=14:color one line of sprite white.

Multicolor Note II: COLUP0 is no longer effective; you can only change the color via the shadow register array. The second sprite is mono color and under control of the COLUP1 register.

*With Flashback BASIC, the rowcolors and player0colors register arrays reside in the top 1.5 rows of the virtual world due to RAM constraints so you must define them programmatically or set the bits in the top row.


Multiple Virtual Worlds (Flashback BASIC only)
----------------------------------------------- 
Flashback BASIC supports multiple virtual worlds and reloading virtual worlds after they have been changed. Set temp variable a to 0 or 1 to specify the first or second virtual world, and call loadvirtualworld:

10 a=0:gosub loadvirtualworld: rem load the first virtual world image

A second ASCII art virtual world may be defined as virtualworld2 right below the virtualworld ASCII art.

10 a=1:gosub loadvirtualworld: rem load the second virtual world image


Padding small programs (Flashback BASIC only)
---------------------------------------------- 
Small programs like examples and demos will work fine in the emulator or on larger Atari consoles, but may not work on the Atari Flashback Portable unless you add padding  the DLI demo shows an example where unused data statements are added to make the program larger.
As your program grows you can remove the unused padding - its only necessary for the Atari Flashback to recognize your program when it is small.


More Information
----------------
Visit RelationalFramework.com for more information about Atari Flashback BASIC, Virtual World BASIC and links to fun and interesting BASIC resources and BASIC game programming contests!

 